package model;

import java.util.*;
import java.util.regex.*;

public class FromQuery {
	private final String fromQuery;
	public FromQuery(String fromQuery) {
		this.fromQuery = fromQuery.toLowerCase();
	}
	public FromQueryData queryParse(){
		try{
			FromQueryData fromQueryData=new FromQueryData();
			List<PairValue> pairValues=new ArrayList<PairValue>();
			fromQueryData.setPairValues(pairValues);
			fromQueryData.setCondition("");
			
			List<String> result=Utilities.SplitByRegex(fromQuery,"from ");
			if(result.size()==1){
				String regex = "(.+)join(.+)on(.+)";
				Pattern p = Pattern.compile(regex);
				Matcher m = p.matcher(result.get(0));
				if (!m.find()) { //khong phai join on
					List<PairValue> returnedList=new ArrayList<PairValue>();
					fromQueryData.setFromQueryType(FromQueryType.NORMAL);
					List<String> items = Utilities.SplitByRegex(fromQuery, "from ");
					if (items.size() == 1) {
						items = Utilities.SplitByRegex(items.get(0), "(,)");
						for (String item : items) {
							List<String> tempItem = Utilities.SplitByRegex(item,
									"( )");
							if (tempItem.size() == 2) {
								returnedList.add(new PairValue(tempItem.get(0),
										tempItem.get(1), true));
							} else if (tempItem.size() == 1) {
								returnedList.add(new PairValue(tempItem.get(0), "",
										false));
							} else {
								return null;
							}
						}
						fromQueryData.setPairValues(returnedList);
						return fromQueryData;
					} else {
						return null;
					}
				}else{ //la join on
					fromQueryData.setFromQueryType(FromQueryType.JOIN);
					if(m.groupCount()==3){
						boolean flag=false;
						for(int i=1;i<=3;i++){
							String groupTemp=m.group(i);
							if(SelectQuery.CheckOpenClose(m.group(i))){
								groupTemp=Utilities.removeAllOpenClose(m.group(i));
							}
							if(i==1){							
								if(!handleJoin(groupTemp,fromQueryData)){
									flag=true;
									List<String> items=Utilities.SplitByRegex(groupTemp,"( )");
									if(items.size()==2){
										PairValue pairValue=new PairValue(items.get(0),items.get(1),true);
										pairValues.add(pairValue);
									}else if(items.size()==1){
										PairValue pairValue=new PairValue(items.get(0),null,false);
										pairValues.add(pairValue);
									}else{
										return null;
									}
								}
								continue;
							}
							if(i==2){
								List<String> items=Utilities.SplitByRegex(groupTemp,"( )");
								if(items.size()==2){
									PairValue pairValue=new PairValue(items.get(0),items.get(1),true);
									pairValues.add(pairValue);
								}else if(items.size()==1){
									PairValue pairValue=new PairValue(items.get(0),null,false);
									pairValues.add(pairValue);
								}else{
									return null;
								}
							}
							if(i==3){
								if(!flag)
									fromQueryData.setCondition(fromQueryData.getCondition()+AddOpenClose(m.group(i),false));
								else
									fromQueryData.setCondition(fromQueryData.getCondition()+m.group(i));
							}
						}
						fromQueryData.setPairValues(pairValues);
						
					}else{
						return null;
					}
				}
			}else{
				return null;
			}
			return fromQueryData;
		}catch(Exception ex){
			return null;
		}
	}
	public boolean handleJoin(String input,FromQueryData data){
		String regex = "(.+)join(.+)on(.+)";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(input);
		if(m.find()){
			for(int i=1;i<=m.groupCount();i++){
				if(i==1){
					Matcher matcher=p.matcher(m.group(i));
					if(matcher.find()){
						if(!handleJoin(m.group(i),data)){
							return false;
						}
					}else{
						List<PairValue> pairValues=data.getPairValues();
						List<String> items = Utilities.SplitByRegex(m.group(i),
								"( )");
						if (items.size() == 2) {
							pairValues.add(new PairValue(items.get(0), items
									.get(1), true));
						} else if (items.size() == 1) {
							pairValues.add(new PairValue(items.get(0), "",
									false));
						} else {
							return false;
						}
						data.setPairValues(pairValues);
					}
					continue;
				}
				if(i==2){
					List<String> items=Utilities.SplitByRegex(m.group(i),"( )");
					List<PairValue> pairValues=data.getPairValues();
					if(items.size()==2){
						PairValue pairValue=new PairValue(items.get(0),items.get(1),true);
						pairValues.add(pairValue);
					}else if(items.size()==1){
						PairValue pairValue=new PairValue(items.get(0),null,false);
						pairValues.add(pairValue);
					}else{
						return false;
					}		
				}
				if(i==3){
					String condition=data.getCondition();
					String temp=m.group(i);
					temp=AddOpenClose(temp,true);					
					data.setCondition(condition+temp);
				}
			}
			return true;
		}else{
			return false;
		}
	}
	private String AddOpenClose(String input,boolean addAND){
		StringBuilder sb=new StringBuilder(input.trim());
		sb.insert(0,'(');
		sb.insert(sb.length(),')');
		if(addAND)
			sb.append("AND");
		return sb.toString();
	}
}
